////////////////////////////////////////////////////////////////////////////////

#ifndef _BUFFER_H_
#define _BUFFER_H_

////////////////////////////////////////////////////////////////////////////////

#include <cstddef>

////////////////////////////////////////////////////////////////////////////////


/** Memory storage for any types
*   
*  @author   Roman Pasechnik
*  @since    Jul 09th, 2009
*  @updated  Nov 15th, 2009
*/
class Buffer
{
////////////////////////////////////////////////////////////////////////////////

public:

////////////////////////////////////////////////////////////////////////////////


    /** Default Constructor */
    Buffer();


    /** Constructor from memory */
    Buffer( const char* _str, size_t _numElems );


    /** Copy constructor */
    Buffer( const Buffer& _rhs );


    /** Assignment operator */
    const Buffer& operator=( const Buffer& _rhs );


////////////////////////////////////////////////////////////////////////////////


    /** Get pointer to data */
    const char* Data() const;


    /** Get buffer size */
    size_t Size() const;


    /** Clear buffer */
    void Clear();


    /** Returns how many bytes can be written before buffer overflow */
    int CountFreeSpace() const;


////////////////////////////////////////////////////////////////////////////////


    /** Internal buffer size */
    enum { MAX_BUFFER_SIZE = 1024 };


////////////////////////////////////////////////////////////////////////////////


    /** Huffman encode */
    void Encode();


    /** Huffman decode */
    void Decode();


////////////////////////////////////////////////////////////////////////////////


    /** Equality operator */
    bool operator==( const Buffer& _rhs ) const;


    /** Inequality operator */
    bool operator!=( const Buffer& _rhs ) const;


////////////////////////////////////////////////////////////////////////////////
// Input and output
////////////////////////////////////////////////////////////////////////////////
    

    /** Write memory */
    void WriteMemory( const void* _memory, size_t _size );


    /** Read memory */
    void ReadMemory( void* _memory, size_t _size );


////////////////////////////////////////////////////////////////////////////////


    /** Write size_t */
    void WriteSize_t( size_t _number );


    /** Read size_t */
    size_t ReadSize_t();


////////////////////////////////////////////////////////////////////////////////


    /** Write int */
    void WriteInt( int _number );


    /** Read int */
    int ReadInt();


////////////////////////////////////////////////////////////////////////////////


    /** Write unsigned int */
    void WriteUInt( unsigned int _number );


    /** Read unsigned int */
    unsigned int ReadUInt();


////////////////////////////////////////////////////////////////////////////////

    /** Write double */
    void WriteDouble( double _number );


    /** Read double */
    double ReadDouble();


////////////////////////////////////////////////////////////////////////////////


    /** Write float */
    void WriteFloat( float _number );


    /** Read float */
    float ReadFloat();


////////////////////////////////////////////////////////////////////////////////

private:

////////////////////////////////////////////////////////////////////////////////


    /** Assign string to buffer */
    void Assign( const char* _str, size_t _size );


////////////////////////////////////////////////////////////////////////////////


    /** Buffer data */
    char m_Data[MAX_BUFFER_SIZE];


    /* Begin of the buffer */
    size_t m_BeginIdx;


    /* End of the buffer */
    size_t m_EndIdx;


////////////////////////////////////////////////////////////////////////////////
};


////////////////////////////////////////////////////////////////////////////////

#endif

////////////////////////////////////////////////////////////////////////////////
